package ignite.lang

import javax.cache.processor.MutableEntry

import org.apache.ignite.IgniteCache
import org.apache.ignite.cache.CacheEntryProcessor
import org.apache.ignite.lang._
import org.apache.ignite.{stream => istream}

import scala.reflect.ClassTag

/**
  * Created by Administrator on 2017/11/14.
  */
trait FnConverter {
  implicit def toIgniteRunnable(act: => Unit) = new IgniteRunnable {
    def run = act
  }

  implicit def toIgniteCallable[R](act: => R) = new IgniteCallable[R] {
    def call = act
  }

  implicit def toIgniteClosure[F, T](act: F => T) = new IgniteClosure[F, T] {

    def apply(f: F) = act(f)
  }

  implicit def toIgnitePredicate[F](act: F => Boolean) = new IgnitePredicate[F] {
    override def apply(e: F): Boolean = act(e)
  }

  implicit def toIgniteBiInClosure[E1, E2](act: (E1, E2) => Unit) = new IgniteBiInClosure[E1, E2] {
    override def apply(e1: E1, e2: E2): Unit = act(e1, e2)
  }

  implicit def toIgniteBiPredicate[E1, E2](act: (E1, E2) => Boolean) = new IgniteBiPredicate[E1, E2] {
    override def apply(e1: E1, e2: E2): Boolean = act(e1, e2)
  }

  implicit def toCacheEntryProcessor[K, V, T](act: (MutableEntry[K, V], Seq[Object]) => T) =
    new CacheEntryProcessor[K, V, T] {
      override def process(entry: MutableEntry[K, V], arguments: Object*): T = {
        act(entry, arguments)
      }
    }

  implicit def toCacheEntryProcessor2[K, V, T](act: (MutableEntry[K, V]) => T) =
    toCacheEntryProcessor[K,V,T] { case (entry, args) => act(entry) }


  implicit class IgniteCacheWrapper[K,V](v:IgniteCache[K,V]){
    def exec[T](k:K)(act: (MutableEntry[K, V]) => T):T=
      v.invoke(k,act)
    def exec[T](k:K,args:Object*)(act: (MutableEntry[K, V], Seq[Object]) => T):T=
      v.invoke(k,act,args:_*)
  }

  object StreamVisitor {
    def from[K, V](act: (IgniteCache[K, V], java.util.Map.Entry[K, V]) => Unit) =
      istream.StreamVisitor.from[K, V](act)
  }

}

object FnConverter extends FnConverter